package sg.edu.nus.iss.billing.controller;

import java.beans.ExceptionListener;
import java.util.Date;
import java.util.List;

import sg.edu.nus.iss.billing.constant.ErrorCodeConstants;
import sg.edu.nus.iss.billing.datastore.DBFactory;
import sg.edu.nus.iss.billing.datastore.IDataStore;
import sg.edu.nus.iss.billing.datastore.impl.Selector;
import sg.edu.nus.iss.billing.entity.ComplaintStatus;
import sg.edu.nus.iss.billing.entity.Customer;
import sg.edu.nus.iss.billing.entity.CustomerComplaint;
import sg.edu.nus.iss.billing.entity.RecordState;
import sg.edu.nus.iss.billing.exception.ControllerException;
import sg.edu.nus.iss.billing.exception.DataStoreException;
import sg.edu.nus.iss.billing.localization.MessageKeyManager;
import sg.edu.nus.iss.billing.util.Util;

public class CustomerComplaintController {

	private IDataStore dataStorage;

	public CustomerComplaintController() {
		this.dataStorage = DBFactory.instance().getSDStore();
	}

	public List<CustomerComplaint> getAllCustomerComplaints()
			throws ControllerException {
		List<CustomerComplaint> customerComplaintList = null;
		Selector selector = new Selector();
		selector.eq("active", RecordState.ACTIVE);
		try {
			customerComplaintList = this.dataStorage.loadObjectsBySelector(
					CustomerComplaint.class, selector);
		} catch (DataStoreException e) {
			throw new ControllerException(ErrorCodeConstants.ERROR_DATASTORE,
					MessageKeyManager.getMessage("error.dataStore"));
		}

		if (Util.isEmpty(customerComplaintList))
			throw new ControllerException(
					ErrorCodeConstants.ERROR_CUSTOMER_COMPLAINT_NOT_FOUND,
					MessageKeyManager
							.getMessage("error.customerComplaintNotFound"));

		return customerComplaintList;
	}

	public List<CustomerComplaint> getCustomerComplaintByNRIC(
			Customer customerObj) throws ControllerException {
		return getCustomerComplaintByNRIC(customerObj.getNRIC());
	}

	public List<CustomerComplaint> getCustomerComplaintByNRIC(
			String customerNRIC) throws ControllerException {
		List<CustomerComplaint> customerComplaintList = null;
		// check customer exists or not
		CustomerController customerController = new CustomerController();
		if (customerController.isNRICExist(customerNRIC) == null) {
			throw new ControllerException(
					ErrorCodeConstants.ERROR_CUSTOMER_NOT_FOUND,
					MessageKeyManager.getMessage("error.customerNotFound"));
		} else {
			Selector selector = new Selector();

			selector.eq("NRIC", customerNRIC.toUpperCase()).eq("active",
					RecordState.ACTIVE);
			try {
				customerComplaintList = this.dataStorage.loadObjectsBySelector(
						CustomerComplaint.class, selector);
			} catch (DataStoreException e) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_DATASTORE,
						MessageKeyManager.getMessage("error.dataStore"));
			}
			if (Util.isEmpty(customerComplaintList)) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_CUSTOMER_COMPLAINT_NOT_EXIST,
						MessageKeyManager
								.getMessage("error.customerComplaintNotExist"));
			}

			return customerComplaintList;
		}
	}

	public CustomerComplaint getCustomerComplaintByReference(
			String complaintRefKey) throws ControllerException {
		List<CustomerComplaint> customerComplaintList = null;
		CustomerComplaint customerComplaintObj = null;
		Selector selector = new Selector();
		selector.eq("complaintRefKey", complaintRefKey.toUpperCase());
		selector.eq("active", RecordState.ACTIVE);
		try {
			customerComplaintList = this.dataStorage.loadObjectsBySelector(
					CustomerComplaint.class, selector);
		} catch (DataStoreException e) {
			throw new ControllerException(ErrorCodeConstants.ERROR_DATASTORE,
					MessageKeyManager.getMessage("error.dataStore"));
		}
		if (customerComplaintList != null && customerComplaintList.size() > 0) {
			customerComplaintObj = customerComplaintList.get(0);
		} else {
			throw new ControllerException(
					ErrorCodeConstants.ERROR_CUSTOMER_COMPLAINT_NOT_FOUND,
					MessageKeyManager
							.getMessage("error.customerComplaintNotFound"));
		}
		return customerComplaintObj;
	}

	public CustomerComplaint findCustomerComplaintByReference(
			String complaintRefKey) throws ControllerException {
		List<CustomerComplaint> customerComplaintList = null;
		CustomerComplaint customerComplaintObj = null;
		Selector selector = new Selector();
		selector.eq("complaintRefKey", complaintRefKey.toUpperCase());
		try {
			customerComplaintList = this.dataStorage.loadObjectsBySelector(
					CustomerComplaint.class, selector);
		} catch (DataStoreException e) {
			throw new ControllerException(ErrorCodeConstants.ERROR_DATASTORE,
					MessageKeyManager.getMessage("error.dataStore"));
		}
		if (customerComplaintList != null && customerComplaintList.size() > 0) {
			customerComplaintObj = customerComplaintList.get(0);
		}
		return customerComplaintObj;
	}

	public List<CustomerComplaint> getComplaintsByDate(Date date)
			throws ControllerException {
		List<CustomerComplaint> customerComplaintList = null;
		Selector selector = new Selector();
		selector.eq("reportedDate", date);
		try {
			customerComplaintList = this.dataStorage.loadObjectsBySelector(
					CustomerComplaint.class, selector);
		} catch (DataStoreException e) {
			throw new ControllerException(ErrorCodeConstants.ERROR_DATASTORE,
					MessageKeyManager.getMessage("error.dataStore"));
		}
		return customerComplaintList;
	}

	public void addCustomerComplaint(CustomerComplaint customerComplaintObj)
			throws ControllerException {
		// check customer exists or not
		CustomerController customerController = new CustomerController();
		if (customerController.isNRICExist(customerComplaintObj.getNRIC()) == null)
			throw new ControllerException(
					ErrorCodeConstants.ERROR_CUSTOMER_NOT_FOUND,
					MessageKeyManager.getMessage("error.customerNotFound"));
		else {
			try {

				// set customerComplaint as active
				customerComplaintObj.setActive(RecordState.ACTIVE);
				customerComplaintObj.setStatus(ComplaintStatus.PENDING);
				this.dataStorage.saveObject(customerComplaintObj);

			} catch (DataStoreException e) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_DATASTORE,
						MessageKeyManager.getMessage("error.dataStore"));
			}
		}
	}

	public void deleteCustomerComplaint(CustomerComplaint customerComplaintObj)
			throws ControllerException {
		if (validateComplaintID(customerComplaintObj)) {
			try {
				// set customerComplaint as disactive
				customerComplaintObj.setActive(RecordState.DELETED);
				this.dataStorage.saveObject(customerComplaintObj);
			} catch (DataStoreException e) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_DATASTORE,
						MessageKeyManager.getMessage("error.dataStore"));
			}
		}
	}

	public void editCustomerComplaint(CustomerComplaint customerComplaintObj)
			throws ControllerException {
		if (validateComplaintID(customerComplaintObj)) {
			try {
				this.dataStorage.saveObject(customerComplaintObj);
			} catch (DataStoreException e) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_DATASTORE,
						MessageKeyManager.getMessage("error.dataStore"));
			}
		}
	}

	public boolean validateComplaintID(CustomerComplaint customerComplaintObj)
			throws ControllerException {
		String complaintID = customerComplaintObj.getId();
		if (Util.isEmpty(complaintID)) {
			throw new ControllerException(
					ErrorCodeConstants.ERROR_CUSTOMER_COMPLAINT_NOT_FOUND,
					MessageKeyManager
							.getMessage("error.customerComplaintNotFound"));
		} else {
			return true;
		}
	}

	public void updateCustomerComplaintStatus(
			CustomerComplaint customerComplaintObj, ComplaintStatus status)
			throws ControllerException {
		if (validateComplaintID(customerComplaintObj)) {
			try {
				customerComplaintObj.setStatus(status);
				dataStorage.saveObject(customerComplaintObj);
			} catch (DataStoreException e) {
				throw new ControllerException(
						ErrorCodeConstants.ERROR_DATASTORE,
						MessageKeyManager.getMessage("error.dataStore"));
			}
		}
	}

}
